package farmer.game;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import core.game.StateBasedGame;
import core.state.BasicState;

import farmer.core.Building;
import farmer.gui.BuildingGUI;
import farmer.gui.MainGameGUI;
import farmer.gui.Minimap;
import farmer.render.building.Map;
import farmer.render.doodad.Tree;

public class MainGameState extends BasicState{

	public MainGameState(StateBasedGame game, int stateID) {
		super(game, stateID);
	}
	
	public static final int width = 800;
	public static final int height = 600;

	int sizeX = 51;
	int sizeY = 51;
	Map map;
	public double translateX = -((sizeX/2-12)*Map.cellWidth);
	public double translateY = -((sizeX/2-8)*Map.cellWidth);
	double translateSpeed = 0.7;
	Minimap minimap;
	
	BuildingGUI gui;
	MainGameGUI gui2;
	Mission mission;
	
	public double getTranslateX(){
		return translateX;
	}
	
	public double getTranslateY(){
		return translateY;
	}
	
	public void setTranslatePosition(int translateX, int translateY){
		this.translateX = translateX;
		this.translateY = translateY;
		if(translateX > 35*7){
			translateX = 35*7;
		}
		if(translateY > 35*3){
			translateY = 35*3;
		}
		if(translateX < -35*(32)){
			translateX = -35*(32);
		}
		if(translateY < -35*(37)){
			translateY = -35*(37);
		}
	}
	
	@Override
	public void mousePressed(MouseEvent e){
		if(Data.status == Data.failed){
			return;
		}
		if(glassPane.isOverGUI(e.getX(), e.getY())){
			return;
		}
		if(e.getButton() == MouseEvent.BUTTON1){
			int mouseX = e.getX();
			int mouseY = e.getY();
			int posX = (int) ((mouseX-translateX)/Map.cellWidth);
			int posY = (int) ((mouseY-translateY)/Map.cellWidth);
			map.selectBuilding(posX, posY);
		}
		if(e.getButton() == MouseEvent.BUTTON3){
			int mouseX = e.getX();
			int mouseY = e.getY();
			int posX = (int) ((mouseX-translateX)/Map.cellWidth);
			int posY = (int) ((mouseY-translateY)/Map.cellWidth);
			map.tryToMakeLink(posX, posY);
		}
	}
	
	@Override
	public void keyPressed(KeyEvent e){
		if(Data.status == Data.failed){
			if(e.getKeyCode() == KeyEvent.VK_R){
				init();
				Data.status = Data.running;
			}
		}else{
			//Launch menu
			if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
				InGameMenuState.image = getImage();
				Data.status = Data.paused;
				getGame().enterState(FarmerBoyGame.InGameMenu);
			}
		}
	}

	@Override
	public synchronized void init() {
		Data.building = Data.none;
		glassPane.reset();
		map = new Map(sizeX, sizeY);
		minimap = new Minimap(map, this);
		translateX = -((sizeX/2-12)*Map.cellWidth);
		translateY = -((sizeX/2-8)*Map.cellWidth);
		map.generateMap();
		gui = new BuildingGUI(this);
		gui2 = new MainGameGUI(this);
		this.getGlassPane().addComponent(minimap);
		mission = new Mission();
		Data.status = Data.running;
	}
	
	public BufferedImage getImage(){
		BufferedImage image = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
		Graphics g = image.getGraphics();
		render((Graphics2D) g);
		return image;
	}

	BasicStroke stroke = new BasicStroke(5);
	Font font = new Font("RessourceLabel", Font.BOLD, 15);
	Font font2 = new Font("RessourceLabel", Font.BOLD, 170);
	Font font3 = new Font("RessourceLabel", Font.BOLD, 30);
	Color color = new Color(1.0f, 0.f, 0f, 0.7f);

	
	@Override
	public synchronized void render(Graphics2D g) {
		//Draw map
		g.translate(translateX, translateY);
		map.draw(g);
		//Draw Selection
		if(Data.building != -1){
			int mouseX = input.getMouseX();
			int mouseY = input.getMouseY();
			if(mouseX >= 100 && mouseX <800 && mouseY>=0 && mouseY <600){
				int posX = (int) ((mouseX-translateX)/Map.cellWidth);
				int posY = (int) ((mouseY-translateY)/Map.cellWidth);
				int size = Data.getSize(Data.building);
				if(Data.building != Data.destroy){
					if(map.isBuildable(posX, posY, size)){
						Color color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
						g.setColor(color);
						g.fillRect(posX*Map.cellWidth, posY*Map.cellWidth, size*Map.cellWidth, size*Map.cellWidth);
					}else{
						Color color = new Color(0.5f, 0f, 0f, 0.5f);
						g.setColor(color);
						g.fillRect(posX*Map.cellWidth, posY*Map.cellWidth, size*Map.cellWidth, size*Map.cellWidth);
					}
				}else{
					if(map.hasBuilding(posX, posY)){
						size = map.getSizeBuilding(posX, posY);
						int x = map.getPosXBuilding(posX, posY);
						int y = map.getPosYBuilding(posX, posY);
						Color color = new Color(0.5f, 0f, 0f, 1.0f);
						g.setColor(color);
						g.setStroke(stroke);
						g.drawLine((x+size)*Map.cellWidth, y*Map.cellWidth, x*Map.cellWidth, (y+size)*Map.cellWidth);
						g.drawLine(x*Map.cellWidth, y*Map.cellWidth, (x+size)*Map.cellWidth, (y+size)*Map.cellWidth);
					}else{
						Color color = new Color(0.5f, 0f, 0f, 0.5f);
						g.setColor(color);
						g.setStroke(stroke);
						g.drawLine((posX+1)*Map.cellWidth, posY*Map.cellWidth, posX*Map.cellWidth, (posY+1)*Map.cellWidth);
						g.drawLine(posX*Map.cellWidth, posY*Map.cellWidth, (posX+1)*Map.cellWidth, (posY+1)*Map.cellWidth);
					}
				}
			}
		}
		//Untranslate
		g.translate(-translateX, -translateY);
		//Draw GUI
		if(Data.status != Data.failed){
			gui.draw(g);
			gui2.draw(g);
			glassPane.draw(g);
		}
		//Draw ressource label
		int h = 8;
		int w = -10;
		g.setColor(new Color(188, 187, 143));//g.setColor(Color.white);
		g.fillRoundRect(300+w, 0+h, 330, 25, 10, 10);
		g.setColor(Color.black);
		//g.setColor(new Color(0.3f, 0.3f, 0.3f, 1f));
		g.setStroke(stroke);
		g.drawRoundRect(300+w, 2+h, 330, 23, 10, 10);
		g.setFont(font);
		g.setColor(new Color(247, 197, 23));
		g.drawString("Food : " + Data.food, 310+w, 20+h);
		g.setColor(new Color(0.3f, 0.3f, 0.3f, 1f));
		g.drawString("--", 390+w, 20+h);
		g.setColor(new Color(165, 92, 12));
		g.drawString("        Wood : " + Data.wood, 390+w, 20+h);
		g.setColor(new Color(0.3f, 0.3f, 0.3f, 1f));
		g.drawString("--", 509+w, 20+h);
		g.setColor(Color.gray);
		g.drawString("        Rock : " + Data.rock, 509+w, 20+h);
		//Draw mission label
		g.setColor(new Color(188, 187, 143));//g.setColor(Color.white);
		g.fillRoundRect(300+w, 30+h, 330, 25, 10, 10);
		g.setColor(Color.black);
		//g.setColor(new Color(0.3f, 0.3f, 0.3f, 1f));
		g.setStroke(stroke);
		g.drawRoundRect(300+w, 32+h, 330, 23, 10, 10);
		g.setFont(font);
		g.setColor(new Color(251, 54, 19));
		g.drawString("Food objective : " + mission.getFood(), 310+w, 50+h);
		g.setColor(new Color(0.3f, 0.3f, 0.3f, 1f));
		g.drawString("--      Time left : " + mission.getTime(), 470+w, 50+h);
		//Draw mission status
		if(Data.status == Data.failed){
			g.setFont(font2);
			g.setColor(color);
			g.drawString("Mission", 140, 250);
			g.drawString("Failed", 200, 420);
			g.setFont(font3);
			g.drawString("< PRESS 'R' to restart the game >", 215, 550);
		}
	}

	@Override
	public synchronized void update(int deltaTime) {
		if(Data.status == Data.failed){
			return;
		}
		mission.update(deltaTime);
		gui.update();
		map.update(deltaTime);
		//Build a building
		if(input.isMouseDown(MouseEvent.BUTTON1)){
			int mouseX = input.getMouseX();
			int mouseY = input.getMouseY();
			if(!getGlassPane().isOverGUI(mouseX, mouseY)){
				if(mouseX >= 100 && mouseX <800 && mouseY>=0 && mouseY <600){
					int posX = (int) ((mouseX-translateX)/Map.cellWidth);
					int posY = (int) ((mouseY-translateY)/Map.cellWidth);
					if(Data.hasRessourceToBuild()){
						if(Data.building==Data.tree){
							//Tree
							Tree tree = new Tree(posX, posY);
							if(map.isBuildable(posX, posY, 1)){
								map.addDoodad(tree);
							}
						}else if(Data.building==Data.destroy){
							//Destroy
							if(map.hasBuilding(posX, posY)){
								map.destroyBuilding(posX, posY);
							}
						}else{
							//All the other building
							Building building = Data.getBuilding(posX, posY, Data.building);
							if(building != null){
								if(map.isBuildable(building.getX(), building.getY(), building.getSize()))
									map.addBuilding(building);
							}
						}
					}
				}
			}
		}
		//Update the map position
		if(input.isKeyPressed(KeyEvent.VK_LEFT) || input.isKeyPressed(KeyEvent.VK_A) || buttonLeft){
			translateX += translateSpeed*deltaTime;
		}
		if(input.isKeyPressed(KeyEvent.VK_RIGHT) || input.isKeyPressed(KeyEvent.VK_D) || buttonRight){
			translateX -= translateSpeed*deltaTime;
		}
		if(input.isKeyPressed(KeyEvent.VK_UP) || input.isKeyPressed(KeyEvent.VK_W) || buttonUp){
			translateY += translateSpeed*deltaTime;
		}
		if(input.isKeyPressed(KeyEvent.VK_DOWN) || input.isKeyPressed(KeyEvent.VK_S) || buttonDown){
			translateY -= translateSpeed*deltaTime;
		}
		if(translateX > 35*7){
			translateX = 35*7;
		}
		if(translateY > 35*3){
			translateY = 35*3;
		}
		if(translateX < -35*(32)){
			translateX = -35*(32);
		}
		if(translateY < -35*(37)){
			translateY = -35*(37);
		}
	}
	
	public boolean buttonUp = false;
	public boolean buttonDown = false;
	public boolean buttonLeft = false;
	public boolean buttonRight = false;

	@Override
	public void enter() {
		if(Data.status == Data.paused){
			Data.status = Data.running;
		}else{
			init();
		}
	}

	

}
